package com.sh.data.engine.web.webapi.controller.normalization;

import com.sh.data.engine.application.model.dto.base.PagerResponse;
import com.sh.data.engine.application.model.dto.dataasset.TableInfoBizDTO;
import com.sh.data.engine.application.model.dto.integration.PreviewDataDTO;
import com.sh.data.engine.application.model.dto.normalization.index.AssociatedTaskResponse;
import com.sh.data.engine.application.model.dto.normalization.index.IndexCatalogResponse;
import com.sh.data.engine.application.model.dto.normalization.index.IndexResponse;
import com.sh.data.engine.application.model.request.normalization.*;
import com.sh.data.engine.application.service.normalization.IndexMgtApplicationService;
import com.sh.data.engine.common.enumDefinition.ProjectStatisticTypeEnum;
import com.sh.data.engine.domain.annotation.LogExecution;
import com.sh.data.engine.domain.annotation.ProjectStatisticExecution;
import com.sh.data.engine.domain.annotation.userlog.Business;
import com.sh.data.engine.domain.annotation.userlog.EngineOperation;
import com.sh.data.engine.domain.datadev.offline.model.domain.OfflineDevDirTreeDomain;
import com.sh.data.engine.domain.normalization.research.dataowner.model.domain.DataOwnerDomain;
import com.sh.data.engine.web.webapi.controller.base.response.RestResponseEntity;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.io.IOException;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @author: mengzheng.mhc
 * @date: 2024/7/4 13:36
 */
@Validated
@Slf4j
@RestController
@RequestMapping("/index")
@Tag(name = "指标定义-指标管理", description = "指标定义-指标管理API")
public class IndexMgtController {

    @Autowired
    private IndexMgtApplicationService indexMgtApplicationService;

    //    @AuthorityAnnotation(menuId = MenuEnumNew.ZBDY, readWriteStatus = 0, isAdd = 1)
    @GetMapping("/listCatalog")
    @Operation(summary = "获取指标目录(后端没有做树形结构封装)")
    public RestResponseEntity<List<IndexCatalogResponse>> listCatalog() {
        var result = indexMgtApplicationService.listCatalog();
        return RestResponseEntity.success(result);
    }

    //    @AuthorityAnnotation(menuId = MenuEnumNew.ZBDY, readWriteStatus = 0, isAdd = 1)
    @GetMapping("/listCatalogWithTree")
    @Operation(summary = "获取指标目录(后端做了树形结构封装)")
    public RestResponseEntity<List<IndexCatalogResponse>> listCatalogWithTree() {
        var result = indexMgtApplicationService.listCatalogWithTree();
        return RestResponseEntity.success(result);
    }

    //    @AuthorityAnnotation(menuId = MenuEnumNew.ZBDY, readWriteStatus = 1, isAdd = 1)
    @PostMapping("/addCatalog")
    @LogExecution(operation = EngineOperation.ADD, business = Business.指标目录)
//    @Log(
//        business = Business.指标目录,
//        operation = Operation.ADD)
    @Operation(summary = "新增指标目录")
    public RestResponseEntity<Boolean> addCatalog(
        @RequestParam String name, @RequestParam(required = false) Long pid) {
        var result = indexMgtApplicationService.addCatalog(name, pid);
        return RestResponseEntity.success(result);
    }

    //    @AuthorityAnnotation(menuId = MenuEnumNew.ZBDY, readWriteStatus = 1, isAdd = 1)
    @PostMapping("/editCatalog")
    @LogExecution(operation = EngineOperation.UPDATE, business = Business.指标目录)
//    @Log(
//        business = Business.指标目录,
//        operation = Operation.UPDATE)
    @Operation(summary = "编辑指标目录(仅支持修改名字)")
    public RestResponseEntity<Boolean> editCatalog(@RequestParam String name, @RequestParam Long id) {
        var result = indexMgtApplicationService.editCatalog(name, id);
        return RestResponseEntity.success(result);
    }

    //    @AuthorityAnnotation(menuId = MenuEnumNew.ZBDY, readWriteStatus = 1, isAdd = 1)
    @PostMapping("/delCatalog")
    @LogExecution(operation = EngineOperation.DEL, business = Business.指标目录)
//    @Log(
//        business = Business.指标目录,
//        operation = Operation.DEL)
    @Operation(summary = "删除指标目录(有子目录不能删除)")
    public RestResponseEntity<Boolean> delCatalog(@RequestParam Long id) {
        var result = indexMgtApplicationService.deleteCatalog(id);
        return RestResponseEntity.success(result);
    }

    //    @AuthorityAnnotation(menuId = MenuEnumNew.ZBDY, readWriteStatus = 0, isAdd = 1)
    @Operation(summary = "获取所有部门(数据owner)")
    @GetMapping(value = "/getDepartList")
    public RestResponseEntity<List<DataOwnerDomain>> getDepartList() {
        return new RestResponseEntity<>(Collections.emptyList());
    }

    //    @AuthorityAnnotation(menuId = MenuEnumNew.ZBDY, readWriteStatus = 1, isAdd = 1)
    @PostMapping("/saveIndex")
    @LogExecution(operation = EngineOperation.ADD, business = Business.指标管理)
//    @Log(
//        business = Business.指标管理,
//        operation = Operation.ADD)
    @Operation(summary = "新建或编辑指标")
    @ProjectStatisticExecution(type = ProjectStatisticTypeEnum.INDEX)
    public RestResponseEntity<Boolean> addIndex(@Valid @RequestBody IndexRequest indexRequest) {
        var result = indexMgtApplicationService.addIndex(indexRequest);
        return RestResponseEntity.success(result);
    }

    //    @AuthorityAnnotation(menuId = MenuEnumNew.ZBDY, readWriteStatus = 1, isAdd = 1)
    @PostMapping("/addIndexVersion")
    @LogExecution(operation = EngineOperation.ADD_VERSION, business = Business.指标管理)
//    @Log(
//        business = Business.指标管理,
//        operation = Operation.ADD_VERSION)
    @Operation(summary = "新增指标版本")
    public RestResponseEntity<Boolean> addIndexVersion(
        @Valid @RequestBody IndexRequest indexRequest) {
        var result = indexMgtApplicationService.addIndexVersion(indexRequest);
        return RestResponseEntity.success(result);
    }

    // 参数是下面这种复杂的格式只能用post去请求了
//    @AuthorityAnnotation(menuId = MenuEnumNew.ZBDY, readWriteStatus = 0, isAdd = 1)
    @PostMapping("/indexList")
    @Operation(summary = "指标的列表")
    public RestResponseEntity<PagerResponse<IndexResponse>> indexList(
        @Valid @RequestBody IndexListRequest indexListRequest) {
        var result = indexMgtApplicationService.indexList(indexListRequest);
        return RestResponseEntity.success(result);
    }

    //    @AuthorityAnnotation(menuId = MenuEnumNew.ZBDY, readWriteStatus = 0, isAdd = 1)
    @GetMapping("/indexDetail")
    @Operation(summary = "指标详情")
    public RestResponseEntity<IndexResponse> indexDetail(@RequestParam Long id) {
        var result = indexMgtApplicationService.indexDetail(id);
        return RestResponseEntity.success(result);
    }

    //    @AuthorityAnnotation(menuId = MenuEnumNew.ZBDY, readWriteStatus = 1, isAdd = 1)
    @GetMapping("/delIndex")
    @LogExecution(operation = EngineOperation.DEL, business = Business.指标管理)
//    @Log(
//        business = Business.指标管理,
//        operation = Operation.DEL)
    @Operation(summary = "删除指标")
    @ProjectStatisticExecution(type = ProjectStatisticTypeEnum.INDEX)
    public RestResponseEntity<Boolean> delIndex(@RequestParam Long id) {
        var result = indexMgtApplicationService.deleteIndex(id);
        return RestResponseEntity.success(result);
    }

    //    @AuthorityAnnotation(menuId = MenuEnumNew.ZBDY, readWriteStatus = 0, isAdd = 1)
    @GetMapping("/getTableList")
    @Operation(summary = "选择结果表（查询该空间下的表列表）")
    public RestResponseEntity<List<TableInfoBizDTO>> getTables() {
        var result = indexMgtApplicationService.getTables();
        return RestResponseEntity.success(result);
    }

    //    @AuthorityAnnotation(menuId = MenuEnumNew.ZBDY, readWriteStatus = 0, isAdd = 1)
    @GetMapping("/getData")
    @Operation(summary = "数据预览(前10条数据),用于对结果表的预览")
    public RestResponseEntity<PreviewDataDTO> getData(@RequestParam String targetTblName) {
        var result = indexMgtApplicationService.getData(targetTblName);
        return RestResponseEntity.success(result);
    }

    //    @AuthorityAnnotation(menuId = MenuEnumNew.ZBDY, readWriteStatus = 0, isAdd = 1)
    @PostMapping("/filterSort")
    @Operation(summary = "对数据筛选排序")
    public RestResponseEntity<PreviewDataDTO> filterSort(
        @Valid @RequestBody FilterSortRequest filterSortRequest) {
        var result = indexMgtApplicationService.filterSort(filterSortRequest);
        return RestResponseEntity.success(result);
    }

    //    @AuthorityAnnotation(menuId = MenuEnumNew.ZBDY, readWriteStatus = 0, isAdd = 1)
    @GetMapping("/getDataAll")
    @Operation(summary = "查看所有数据(select *)，第一次查询的时候调用此接口")
    public RestResponseEntity<PreviewDataDTO> getDataAll(@RequestParam String targetTblName) {
        var result = indexMgtApplicationService.getDataAll(targetTblName);
        return RestResponseEntity.success(result);
    }

    //    @AuthorityAnnotation(menuId = MenuEnumNew.ZBDY, readWriteStatus = 0, isAdd = 1)
    @GetMapping("/getElement")
    @Operation(summary = "查看所有字段的不重复元素")
    public RestResponseEntity<Map<String, Set<String>>> getElement(@RequestParam String targetTblName) {
        var result = indexMgtApplicationService.getElement(targetTblName);
        return RestResponseEntity.success(result);
    }

    /**
     * @description : 指标结果数据导出到excel 这个结果集合存在内存里
     * @author : tinglan.ys
     * @date : 2022/4/25
     */
//    @AuthorityAnnotation(menuId = MenuEnumNew.ZBDY, readWriteStatus = 0, isAdd = 1)
    @GetMapping("indexListExport")
    @Operation(summary = "指标结果数据导出到excel 再查询一遍全量数据")
    @LogExecution(operation = EngineOperation.EXPORT, business = Business.指标管理)
//    @Log(
//        business = Business.指标管理,
//        operation = Operation.EXPORT)
    public void indexListExport(
        HttpServletResponse response,
        @RequestParam String targetTblName,
        @RequestParam Long projectId)
        throws IOException {
        indexMgtApplicationService.indexListExport(response, targetTblName, projectId);
    }

    //    @AuthorityAnnotation(menuId = MenuEnumNew.ZBDY, readWriteStatus = 1, isAdd = 1)
    @PostMapping("/saveIndexCorrelation")
    @Operation(summary = "指标关联保存修改取消，取消就是indexCorrelation里面不塞数据")
    public RestResponseEntity<Boolean> saveIndexCorrelation(
        @RequestBody IndexCorrelationExtenalRequest indexCorrelationRequest) {
        var result = indexMgtApplicationService.saveIndexCorrelation(indexCorrelationRequest);
        return RestResponseEntity.success(result);
    }

    //    @AuthorityAnnotation(menuId = MenuEnumNew.ZBDY, readWriteStatus = 0, isAdd = 1)
    @GetMapping("/getAssociatedTasks")
    @Operation(summary = "根据结果表查询关联任务(离线同步、离线开发、文件采集)")
    public RestResponseEntity<List<AssociatedTaskResponse>> getAssociatedTasks(
        @RequestParam String tableName) {
        var result = indexMgtApplicationService.getAssociatedTasks(tableName);
        return RestResponseEntity.success(result);
    }

    //    @AuthorityAnnotation(menuId = MenuEnumNew.ZBDY, readWriteStatus = 0, isAdd = 1)
    @GetMapping("/offlineTree")
    @Operation(summary = "查询离线开发工作流目录")
    public RestResponseEntity<List<OfflineDevDirTreeDomain>> offlineTree() {
        var result = indexMgtApplicationService.getOfflineTree();
        return RestResponseEntity.success(result);
    }

    @PostMapping("/taskFlow/save")
    @LogExecution(operation = EngineOperation.ADD_UPDATE, business = Business.离线开发elt工作流)
//    @Log(
//        business = Business.离线开发elt工作流,
//        operation = Operation.ADD_UPDATE)
    @Operation(summary = "离线开发保存工作流(点击离线开发按钮，若指标信息包含nodeId前端直接跳转)")
//    @AuthorityAnnotation(menuId = MenuEnumNew.ZBDY, readWriteStatus = 1)
    public RestResponseEntity<Boolean> saveTaskFlow(
        @Valid IndexOfflineDevTaskFlowSaveRequest request) {
        var result = indexMgtApplicationService.saveTaskFlow(request);
        return RestResponseEntity.success(result);
    }
}
